package com.marketfarm.server.service;

import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.jdo.PersistenceManager;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.marketfarm.client.service.UsuarioService;
import com.marketfarm.server.dao.DAO;
import com.marketfarm.server.dao.PMF;
import com.marketfarm.shared.entity.Item;
import com.marketfarm.shared.entity.Item.TipoItem;
import com.marketfarm.shared.entity.Usuario;

public class UsuarioServiceImpl extends RemoteServiceServlet implements UsuarioService {

	private DAO dao = new DAO();
	private Logger log = Logger.getLogger(this.getClass().getName());
	
	@Override
	public void novoUsuario(Usuario usuario) throws Exception{
		if(!emailInexistente(usuario.getEmail())) throw new Exception("Esse email j\u00E1 est\u00E1 cadastrado");
		if(!nickInexistente(usuario.getNick())) throw new Exception("Esse nick j\u00E1 est\u00E1 cadastrado");

		Item maca = dao.buscaUnicaOuNull(Item.class, new String[]{"tipo"}, new Object[]{TipoItem.MACA});
		if(maca == null){
			criarItens();
			maca = dao.buscaUnicaOuNull(Item.class, new String[]{"tipo"}, new Object[]{TipoItem.MACA});
		}
		
		Map<TipoItem, Integer> itens = new HashMap<TipoItem, Integer>();
		itens.put(TipoItem.MACA, 10);
		itens.put(TipoItem.PERA, 10);
		itens.put(TipoItem.TOMATE, 10);
		itens.put(TipoItem.KIWI, 10);
		itens.put(TipoItem.LIMAO, 10);
		
		Map<TipoItem, Integer> itensAVenda = new HashMap<TipoItem, Integer>();
		itensAVenda.put(TipoItem.MACA, 0);
		itensAVenda.put(TipoItem.PERA, 0);
		itensAVenda.put(TipoItem.TOMATE, 0);
		itensAVenda.put(TipoItem.KIWI, 0);
		itensAVenda.put(TipoItem.LIMAO, 0);
		
		usuario.setDinheiro(100D);
		usuario.setQuantidadeItem(itens);
		usuario.setQuantidadeItemAVenda(itensAVenda);
		
		dao.merge(usuario);
	}
	
	private void criarItens() throws Exception{
		log.log(Level.INFO, "Criando itens");
		
		Item maca = new Item();
		maca.setNome("Maça");
		maca.setTipo(TipoItem.MACA);
		maca.setValor(1D);

		Item pera = new Item();
		pera.setNome("Pêra");
		pera.setTipo(TipoItem.PERA);
		pera.setValor(1D);
		
		Item tomate = new Item();
		tomate.setNome("Tomate");
		tomate.setTipo(TipoItem.TOMATE);
		tomate.setValor(1D);
		
		Item kiwi = new Item();
		kiwi.setNome("Kiwi");
		kiwi.setTipo(TipoItem.KIWI);
		kiwi.setValor(1D);
		
		Item limao = new Item();
		limao.setNome("Limão");
		limao.setTipo(TipoItem.LIMAO);
		limao.setValor(1D);
		
		dao.merge(maca);
		dao.merge(pera);
		dao.merge(tomate);
		dao.merge(kiwi);
		dao.merge(limao);
	}

	@Override
	public String login(String nick, String senha, Long avoidCache) throws Exception{
		Usuario usuario = dao.buscaUnicaOuNull(Usuario.class, new String[]{"nick", "senha"}, new String[]{nick, senha}, true);
		
		if(usuario == null) return null;
		
		HttpSession session = getThreadLocalRequest().getSession();
		session.setAttribute("usuarioLogado", usuario);
		
		return session.getId();
	}

	@Override
	public void logout() {
		HttpSession session = getThreadLocalRequest().getSession();
		session.setAttribute("usuarioLogado", null);
	}

	@Override
	public Boolean emailInexistente(String email) throws Exception {
		return dao.buscaUnicaOuNull(Usuario.class, new String[]{"email"}, new String[]{email}) == null;
	}

	@Override
	public Boolean nickInexistente(String nick) throws Exception {
		return dao.buscaUnicaOuNull(Usuario.class, new String[]{"nick"}, new String[]{nick}) == null;
	}

	@Override
	public Boolean sessaoContinuaValida(String sessao, Long avoidCache) throws Exception {
		return sessaoContinuaValida(sessao, getThreadLocalRequest().getSession());
	}
	
	private Boolean sessaoContinuaValida(String sessao, HttpSession session) throws Exception {
		if(session != null && session.getId() != null) return session.getId().equals(sessao);
		
		return false;
	}

	@Override
	public Usuario getUsuario(String sessao, Long avoidCache) throws Exception {
		HttpSession session = getThreadLocalRequest().getSession();
		return getUsuario(sessao, session);
	}
	
	public Usuario getUsuario(String sessao, HttpSession session) throws Exception {
		if(sessaoContinuaValida(sessao, session)){
			Usuario usuario = (Usuario)session.getAttribute("usuarioLogado");
			
			PersistenceManager pm = null;
			try {
				pm = PMF.get().getPersistenceManager();
				usuario = (Usuario)dao.load(pm, usuario);
			} finally {
				pm.close();
			}
			
			return usuario;
		}
		else{
			throw new Exception("Usuário não logado");
		}
	}
	
}
